home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
676-700
/
681
/
term
/
source.lha
/
termRaster.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-14
|
11KB
|
629 lines
/*
** $Id: termRaster.c,v 1.3 92/05/14 09:05:39 olsen Sta Locker: olsen $
** $Revision: 1.3 $
** $Date: 92/05/14 09:05:39 $
**
** Screen character (raster) buffering routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* RasterMarkArea(WORD Column,WORD Line,WORD Length):
*
* Mark an area in the term Buffer window.
*/
STATIC VOID __regargs
RasterMarkArea(WORD Column,WORD Line,WORD Length)
{
STATIC WORD OldColumn = -1,OldLine = -1,OldLength = -1;
if(OldColumn != Column || OldLine != Line || OldLength != Length)
{
if(OldColumn != -1)
ClipBlit(RPort,0,0,RPort,OldColumn * 8,OldLine * 8,OldLength * 8,8,0x50);
if(Column != -1)
ClipBlit(RPort,0,0,RPort,Column * 8,Line * 8,Length * 8,8,0x50);
}
OldColumn = Column;
OldLine = Line;
OldLength = Length;
}
/* RasterClip():
*
* Put a character raster portion into the clipboard.
*/
VOID
RasterClip(BYTE SingleChar,BYTE Xerox)
{
struct IntuiMessage *Massage;
ULONG Code,Class;
BYTE SkipLoop = FALSE;
LONG ThisLine,ThisColumn,MyColumn,SomeColumn;
UBYTE *TheLine;
UBYTE Mask = RPort -> Mask;
SetWrMsk(RPort,0xFF);
/* Remember initial mouse position. */
ThisColumn = Window -> MouseX / 8;
ThisLine = Window -> MouseY / 8;
if(ThisColumn <= LastColumn && ThisLine <= LastLine)
{
RasterMarkArea(-1,-1,-1);
/* Find the approriate line and its length. */
TheLine = &Raster[RasterWidth * ThisLine];
if(SingleChar)
{
if(TheLine[ThisColumn] && TheLine[ThisColumn] != ' ')
{
SerWrite(&TheLine[ThisColumn],1);
if(Xerox)
{
switch(Config . SendCR)
{
case CR_IGNORE: break;
case CR_ASCR: SerWrite("\r",1);
break;
case CR_ASCRLF: SerWrite("\r\n",2);
break;
}
}
}
SetWrMsk(RPort,Mask);
return;
}
/* Resonable dimensions? */
if(ThisColumn <= LastColumn)
{
MyColumn = ThisColumn;
/* Loop until left mouse button is release. */
while(!SkipLoop)
{
WaitPort(Window -> UserPort);
while(Massage = (struct IntuiMessage *)GetMsg(Window -> UserPort))
{
Class = Massage -> Class;
Code = Massage -> Code;
ReplyMsg(Massage);
/* User deactivated window
* (which strange way to do
* this he may ever have
* taken...).
*/
if(Class == IDCMP_INACTIVEWINDOW)
{
SkipLoop = TRUE;
RasterMarkArea(-1,-1,-1);
break;
}
/* We're finished! */
if(Class == IDCMP_MOUSEBUTTONS && (Code & IECODE_UP_PREFIX))
{
SkipLoop = TRUE;
/* Did we get a reasonable mouse
* position?
*/
if(MyColumn != ThisColumn)
{
/* Preserve right order of
* numbers.
*/
if(MyColumn < ThisColumn)
{
LONG Help;
Help = ThisColumn;
ThisColumn = MyColumn;
MyColumn = Help;
}
RasterMarkArea(-1,-1,-1);
/* Clip the contents of the line to
* the clipboard.
*/
SaveClip(&TheLine[ThisColumn],MyColumn - ThisColumn);
if(Xerox)
{
SerWrite(&TheLine[ThisColumn],MyColumn - ThisColumn);
switch(Config . SendCR)
{
case CR_IGNORE: break;
case CR_ASCR: SerWrite("\r",1);
break;
case CR_ASCRLF: SerWrite("\r\n",2);
break;
}
}
}
break;
}
/* The mouse has moved. */
if(Class == IDCMP_MOUSEMOVE)
{
STATIC LONG OldColumn = ~0;
/* Determine new mouse position. */
SomeColumn = MyColumn;
MyColumn = Massage -> MouseX / 8;
if((Massage -> MouseY / 8) < ThisLine)
MyColumn = 0;
if((Massage -> MouseY / 8) > ThisLine)
MyColumn = LastColumn + 1;
/* Don't redraw the line if nothing
* has changed.
*/
if(OldColumn != MyColumn)
{
OldColumn = MyColumn;
/* Reasonable position? */
if(MyColumn <= LastColumn + 1)
{
if(MyColumn >= 0)
{
/* Highlight the selected
* area (invert).
*/
if(MyColumn != ThisColumn)
{
if(MyColumn < ThisColumn)
RasterMarkArea(MyColumn,ThisLine,ThisColumn - MyColumn);
else
RasterMarkArea(ThisColumn,ThisLine,MyColumn - ThisColumn);
}
}
}
else
MyColumn = SomeColumn;
}
}
}
}
}
}
SetWrMsk(RPort,Mask);
}
/* DeleteRaster():
*
* Free the contents of the character raster.
*/
VOID
DeleteRaster()
{
if(Raster)
{
FreeVec(Raster);
Raster = NULL;
}
if(RasterAttr)
{
FreeVec(RasterAttr);
RasterAttr = NULL;
}
}
/* CreateRaster():
*
* Create the character raster.
*/
BYTE
CreateRaster()
{
/* Width of the screen * 2 (in characters).
* extra for Double width
*/
RasterWidth = Window -> Width / 4;
/* Height of the character raster. */
RasterHeight = Window -> Height / 8;
/* Allocate the raster. */
if(!(Raster = (UBYTE *)AllocVec(RasterWidth * RasterHeight,MEMF_ANY|MEMF_CLEAR)))
return(FALSE);
/* Allocate the raster attributes. */
if(!(RasterAttr = (UBYTE *)AllocVec(RasterHeight,MEMF_ANY|MEMF_CLEAR)))
{
FreeVec(Raster);
Raster = NULL;
return(FALSE);
}
return(TRUE);
}
/* RasterEraseScreen(BYTE Mode):
*
* Erase parts of the screen.
*/
VOID __regargs
RasterEraseScreen(BYTE Mode)
{
WORD First,
Last;
switch(Mode)
{
case 1: First = 0;
Last = CursorY * RasterWidth + CursorX + 1;
memset(&RasterAttr[0],SCALE_NORMAL,CursorY + 1);
break;
case 2: First = 0;
Last = RasterHeight * RasterWidth - 1;
memset(&RasterAttr[0],SCALE_NORMAL,RasterHeight);
break;
default:First = CursorY * RasterWidth + CursorX;
Last = RasterHeight * RasterWidth - 1;
memset(&RasterAttr[CursorY],SCALE_NORMAL,RasterHeight - CursorY);
break;
}
if(Last > First)
memset(&Raster[First],' ',Last - First);
}
/* RasterEraseLine(BYTE Mode):
*
* Erase parts of the current cursor line.
*/
VOID __regargs
RasterEraseLine(BYTE Mode)
{
WORD First,
Last;
switch(Mode)
{
/* From beginning to current cursor position. */
case 1: First = CursorY * RasterWidth;
Last = First + CursorX + 1;
break;
/* Entire line. */
case 2: First = CursorY * RasterWidth;
Last = First + RasterWidth - 1;
break;
/* From current cursor position towards end. */
default:First = CursorY * RasterWidth + CursorX;
Last = (CursorY + 1) * RasterWidth - 1;
break;
}
if(Last > First)
memset(&Raster[First],' ',Last - First);
}
/* RasterEraseCharacters(WORD Chars):
*
* Erase a number of characters in the current cursor
* line.
*/
VOID __regargs
RasterEraseCharacters(WORD Chars)
{
if(CursorX < RasterWidth - 1)
{
WORD First,
Diff;
UBYTE *To,
*From;
First = CursorY * RasterWidth + CursorX;
To = &Raster[First];
if(CursorX + Chars >= RasterWidth)
{
Diff = RasterWidth - 1 - CursorX;
while(Diff-- > 0)
*To++ = ' ';
}
else
{
From = &Raster[First + Chars];
Diff = RasterWidth - (CursorX + 1 + Chars);
while(Diff--)
{
*To++ = *From;
*From++ = ' ';
}
}
}
}
/* RasterClearLine(WORD Lines):
*
* Clear and remove a number of lines.
*/
VOID __regargs
RasterClearLine(WORD Lines,WORD Top)
{
if(Lines)
{
WORD RegionBottom;
if(RegionSet)
RegionBottom = Bottom;
else
RegionBottom = LastLine + 1;
if(Top + Lines >= RegionBottom)
RasterEraseScreen(0);
else
{
WORD Max;
UBYTE *From,
*To;
Max = (RegionBottom - (Top + Lines)) * RasterWidth;
From = &Raster[(Top + Lines) * RasterWidth];
To = &Raster[ Top * RasterWidth];
while(Max--)
{
*To++ = *From;
*From++ = ' ';
}
memset(&RasterAttr[RegionBottom - Lines],SCALE_NORMAL,Lines);
}
}
}
/* RasterInsertLine(WORD Lines):
*
* Insert a number of lines at the current cursor line.
*/
VOID __regargs
RasterInsertLine(WORD Lines,WORD Top)
{
if(Lines)
{
WORD RegionBottom;
if(RegionSet)
RegionBottom = Bottom;
else
RegionBottom = LastLine + 1;
if(Top + Lines > RegionBottom)
RasterEraseScreen(0);
else
{
WORD From,To,
Max;
UBYTE *FromPtr,
*ToPtr;
Max = (RegionBottom - Lines - Top) * RasterWidth;
From = (RegionBottom - Lines) * RasterWidth - 1;
To = RegionBottom * RasterWidth - 1;
FromPtr = &Raster[From];
ToPtr = &Raster[To];
while(Max--)
*ToPtr-- = *FromPtr--;
memset(&Raster[Top * RasterWidth],' ',Lines * RasterWidth);
}
}
}
/* RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines):
*
* Scroll the contents of the character raster up/down.
*/
VOID __regargs
RasterScrollRegion(WORD Direction,WORD RasterTop,WORD RasterBottom,WORD RasterLines)
{
WORD Dir = ABS(Direction);
if(Dir >= RasterLines)
{
/* All that is needed is to delete the lines. */
memset(&Raster[RasterTop * RasterWidth],' ',RasterLines * RasterWidth);
}
else
{
WORD First,
Last,
Max,
i;
UBYTE *From,
*To;
Max = (RasterLines - Dir) * RasterWidth;
if(Direction < 0)
{
First = (RasterTop + RasterLines - Dir) * RasterWidth - 1;
Last = (RasterTop + RasterLines ) * RasterWidth - 1;
From = &Raster[First];
To = &Raster[Last];
while(Max--)
*To-- = *From--;
for(i = RasterBottom ; i >= (RasterTop + Dir) ; i--)
RasterAttr[i] = RasterAttr[i - Dir];
memset(&Raster[RasterTop * RasterWidth],' ',RasterWidth * Dir);
memset(&RasterAttr[RasterTop],SCALE_NORMAL,Dir);
}
else
{
First = RasterTop * RasterWidth + RasterWidth * Dir;
Last = RasterTop * RasterWidth;
From = &Raster[First];
To = &Raster[Last];
while(Max--)
*To++ = *From++;
memset(&Raster[(RasterBottom - Dir) * RasterWidth],' ',RasterWidth * Dir);
for(i = RasterTop ; i <= (RasterBottom - Dir) ; i++)
RasterAttr[i] = RasterAttr[i + Dir];
memset(&RasterAttr[RasterBottom - Dir],SCALE_NORMAL,Dir);
}
}
}
/* RasterShiftChar(WORD Size):
*
* Shift the characters following the current cursor
* position Size characters to the right.
*/
VOID __regargs
RasterShiftChar(WORD Size)
{
WORD i,
First;
UBYTE *From,
*To;
if(CursorX + Size >= RasterWidth - 1)
{
i = RasterWidth - 1 - CursorX;
To = &Raster[CursorY * RasterWidth + CursorX];
while(i-- > 0)
*To++ = ' ';
}
else
{
First = (CursorY + 1) * RasterWidth - 1;
To = &Raster[First];
From = &Raster[First - Size];
i = RasterWidth - Size;
while(i-- > CursorX)
*To-- = *From--;
To = &Raster[CursorY * RasterWidth + CursorX];
while(Size--)
*To++ = ' ';
}
}
/* RasterPutString(UBYTE *String,WORD Length):
*
* Put a string into the character raster.
*/
VOID __regargs
RasterPutString(UBYTE *String,WORD Length)
{
if(Length == 1)
{
if(CursorX + 1 < RasterWidth)
Raster[CursorY * RasterWidth + CursorX] = String[0];
}
else
{
if(CursorX + Length >= RasterWidth)
Length = RasterWidth - 1 - CursorX;
if(Length > 0)
memcpy(&Raster[CursorY * RasterWidth + CursorX],String,Length);
}
}